﻿WEBVTT

00:00:00.000 --> 00:00:06.000
Translated by visionNoob, KNU
https://github.com/insurgent92/CS231N_17_KOR_SUB

00:00:06.804 --> 00:00:15.375
시작하겠습니다!

00:00:15.375 --> 00:00:18.257
안녕하세요
저를 처음 보시는분들도 계실텐데요

00:00:18.257 --> 00:00:24.853
제 이름은 Serena Yeung이고
이 강의의 세 번째이자 마지막 강사입니다

00:00:24.853 --> 00:00:28.307
또한 Fei-Fei 교수님 그룹에서 박사 과정 학생입니다

00:00:28.307 --> 00:00:31.292
오늘 우리는 backpropagation과
neural network에 대해 이야기하려 합니다

00:00:31.292 --> 00:00:37.346
우리는 이제부터 이 수업의 핵심이 되는 것을 얻을 것입니다

00:00:37.346 --> 00:00:39.929
시작하기전에 음...

00:00:42.124 --> 00:00:44.166
몇 가지 확인할 사항이 있습니다

00:00:44.166 --> 00:00:47.602
[과제 1]이 4월 20일 목요일까지입니다.

00:00:47.602 --> 00:00:51.522
다시 말씀드리지만, 우리는 마감일을 조금 뒤로 늦췄습니다

00:00:51.522 --> 00:00:55.105
당일 오후 11시59분까지 Canvas에 제출되어야 합니다

00:00:56.722 --> 00:00:59.316
그러므로 당신은 당신의 프로젝트에 대해 신경써야할 것입니다

00:00:59.316 --> 00:01:02.327
Piazza에 전공 TA 리스트가 있습니다

00:01:02.327 --> 00:01:12.682
프로젝트 주제에 대해 궁금한 것이 생기면 관련된
TA들을 찾아보는 것을 고려할 수 있습니다

00:01:12.682 --> 00:01:15.910
그리고 Google Cloud 사용을 위한 100$를 받게 될 것입니다

00:01:15.910 --> 00:01:24.285
과제 및 프로젝트를 위한 것이며 당신은
이번주에 관련 email을 받을 것입니다

00:01:24.285 --> 00:01:31.060
많은 분들이 이미 가지고 있을 수 있지만
없는 사람들을 위해 이번 주말까지 전송될 것입니다

00:01:32.544 --> 00:01:36.621
자, 우리는 어떻게 classifier를 정의하는지
함수 f를 통해 이야기 했었습니다

00:01:36.621 --> 00:01:43.169
weights W를 파라미터로 가지고 있고, 이 함수 f는 데이터 x가 입력(input)이고

00:01:43.169 --> 00:01:51.432
출력(output)은 분류하고자 하는 클래스들에 대한 score vector 입니다

00:01:51.432 --> 00:01:57.314
또한 우리는 loss function을 정의할 수 있습니다
SVM loss function을 예로 들면

00:01:57.314 --> 00:02:07.727
우리가 행복한지 불행한지를 점수로 나타내 이야기 할 때
우리는 total loss 항(term)을 정의해 사용할 수 있습니다

00:02:07.727 --> 00:02:14.617
여기서 loss function은 데이터 항의 조합으로 이루어져
있는데 정규화 항을 포함하고 있습니다

00:02:14.617 --> 00:02:20.201
정규화 항은 얼마나 우리의 모델이 단순한지 더 나은
일반화를 위해 적합한 단순 모델을 가지고 있는지를 표현해줍니다

00:02:20.201 --> 00:02:25.209
또한 우리는 최적의 loss를 갖게 하는 파라미터 W를 찾고 싶습니다

00:02:25.209 --> 00:02:31.497
그래서 우리는 loss function의 W에 관한 gradient를 찾았습니다

00:02:33.275 --> 00:02:35.829
이전 강의에서 어떻게 optimization을 사용해서 구할 수 있는지 이야기 했습니다.

00:02:35.829 --> 00:02:47.291
gradient가 음수인 방향, 즉 경사가 하강하는 방향을 반복적으로 구해
아래로 나아갈 수 있고, 우리는 가장 낮은 loss에 찾게 될 것입니다.

00:02:47.291 --> 00:02:54.770
그리고 우리는 경사 하강법(gradient descent)이 오른쪽
이미지와 같이 기본적으로 이런 궤도를 나타내는 것을 보았습니다.

00:02:54.770 --> 00:03:00.126
 오!

00:03:02.247 --> 00:03:06.154
우리는 또한 gradient를 구하는
다른 방법에 대해서도 이야기했습니다.

00:03:06.154 --> 00:03:10.696
우리는 수학적으로 유한 차분 근사(finite differnce
approximation)를 이용해 계산할 수 있습니다.

00:03:10.696 --> 00:03:14.725
비록 이것은 느리고 또한 근사치이지만
써내려가면서 하기에 가장 쉬운 방법입니다.

00:03:14.725 --> 00:03:17.589
당신은 언제나 이 방법을 이용해 gradient를 얻을 수 있다는 것을 알고 있습니다.

00:03:17.589 --> 00:03:23.113
analytic gradient를 어떻게 사용하지
그리고 계산하는 것까지 이야기했습니다.

00:03:23.113 --> 00:03:25.227
analytic gradient를 사용하는 것은 빠르고 정확합니다.

00:03:25.227 --> 00:03:32.734
하지만 당신은 이 식을 유도하기 위해 많은 수학과 함께 미적분학을 해야 합니다.
또한 실수하기 쉽다는 것을 알아두세요.

00:03:32.734 --> 00:03:34.925
실제로 우리가 원하는것은 analytic gradient를 유도하고 사용하는 것입니다.

00:03:34.925 --> 00:03:44.600
하지만 동시에 analytic gradient를 사용한 응용에 대해서 수학적 검증이 필요합니다.

00:03:46.032 --> 00:03:52.261
그래서 오늘은 임의의 복잡한 함수를 통해 어떻게
analytic gradient를 계산하는지에 대해 이야기할 것입니다.

00:03:52.261 --> 00:03:55.824
computational graph라고 부르는 프레임워크를 사용할 것입니다.

00:03:55.824 --> 00:04:00.555
그리고 기본적으로 computational graph 같은 종류의
그래프를 이용해서 어떤 함수든지 표현할 수 있습니다.

00:04:00.555 --> 00:04:06.611
그리고 그래프의 각 노드는 연산 단계를 나타냅니다.

00:04:06.611 --> 00:04:13.306
예를들면 이 예제는 우리가 말해왔던 input이 x,W인 선형 classifier입니다.

00:04:13.306 --> 00:04:27.478
 곱셈 노드는 행렬 곱셈을 나타냅니다. 파라미터 W와 데이터
x의 곱셈은 score vector를 출력합니다.

00:04:27.478 --> 00:04:31.948
그리고 우리는 hinge loss라는
다른 계산 노드를 가지고 있습니다.

00:04:31.948 --> 00:04:38.198
데이터 항  Lᵢ를 계산하는데, 우리는 오른쪽 하단에 보이
regularization 항 또한 가지고 있습니다.

00:04:38.198 --> 00:04:49.044
이 노드(R)는 regularization 항을 계산하고 우리의 최종
loss는 L은 regularization 항과 데이터 항의 합입니다.

00:04:50.624 --> 00:04:58.103
computational graph를 사용해서 함수를 표현하게 됨으로써
backpropagation이라고 부르는 기술을 사용할 수 있게 됩니다.

00:04:58.103 --> 00:05:05.568
backpropagation은 gradient를 얻기위해 computational graph
내부의 모든 변수에 대해 chain rule을 재귀적으로 사용합니다.

00:05:05.568 --> 00:05:09.830
그리고 우리는 이것이 어떻게 동작하는지 볼 것입니다.

00:05:09.830 --> 00:05:13.413
이것은 우리가 매우 복잡한 함수를 이용하여 작업할때 아주 유용하게 사용됩니다.

00:05:13.413 --> 00:05:20.900
예를들면 우리가 이 수업에서 이야기하게 될 CNN은 가장 윗층(top)에
입력 이미지가 들어가고 아래(bottom)에는 loss가 있습니다.

00:05:20.900 --> 00:05:29.102
입력 이미지는 loss function으로 가기까지 많은 layer를 거쳐 변형을 겪게 됩니다.

00:05:30.896 --> 00:05:33.165
이것은 심지어 상상하는만큼 미칠(crazier) 수 있습니다.

00:05:33.165 --> 00:05:38.869
여러분은 딥러닝의 다른 종류인 neural turing machine을 알고있을텐데요
이 경우의 computational graph를 볼 수 있습니다.

00:05:38.869 --> 00:05:45.797
이것은 아주 미쳤지만 특별합니다.
우리는 결국 시간이 지남에 따라 이것을 풀게 될 것입니다.

00:05:45.897 --> 00:05:53.234
만약 여러분이 어떤 중간 변수의 gradient를
계산하고 싶으면 이것은 기본적으로 아주 비실용적입니다.

00:05:55.560 --> 00:05:59.139
자 어떻게 backpropagation이 동작할까요?
간단한 예제부터 시작해봅시다.

00:05:59.139 --> 00:06:01.838
일단, 우리의 목표는 우리가 함수를 가지는 것입니다.

00:06:01.838 --> 00:06:08.614
이 경우 x,y,z로 구성된 function f는 (x+y)*z와 같습니다.

00:06:08.614 --> 00:06:13.572
그리고 우리는 function f의 출력에 대한 어떤 변수의 gradient를 찾기 원합니다.

00:06:13.572 --> 00:06:17.329
그래서 첫 번째 단계는 항상 함수 f를 이용해서 computational graph로 나타내는 것입니다.

00:06:17.329 --> 00:06:20.623
computational graph가 오른쪽에 있습니다.

00:06:20.623 --> 00:06:30.044
x,y에 대한 덧셈 노드를 보실 수 있으며
오른쪽에는 다음 연산을 위한 곱셈 노드도 가지고 있습니다.

00:06:30.044 --> 00:06:34.060
그리고 이 네트워크에 우리가 가지고 있는 값을 전달할 것입니다.

00:06:34.060 --> 00:06:42.944
x는 -2, y는 5, z는 -4입니다.

00:06:42.944 --> 00:06:49.417
또한 중간중간 값도 계산하여 computational graph에 값을 적어 놓았습니다.

00:06:49.417 --> 00:06:56.990
x+y는 3입니다. 그리고 마지막으로 최종
노드를 통과시켜 -12를 얻습니다.

00:06:56.990 --> 00:07:00.823
여기에서 모든 중간 변수에 이름을 줘봅시다.

00:07:04.310 --> 00:07:10.438
그래서 나는 x+y 덧셈 노드를 q라고 부를 것입니다.

00:07:10.438 --> 00:07:14.997
또한 여기에서 f는 q*z입니다.

00:07:14.997 --> 00:07:24.763
그리고 저는 x와 y에 각각에 대한 q의 gradient를 표시해 놓았습니다.
그것은 단순 덧셈이기때문에 1입니다.

00:07:24.763 --> 00:07:34.607
그리고 q와 z에 대한 f의 gradient는 곱셈규칙에 의해 각각 z와 q입니다.

00:07:34.607 --> 00:07:40.431
그리고 우리가 찾기 원하는것은 x,y,z 각각에 대한 f의 gradient입니다.

00:07:43.356 --> 00:07:49.182
backpropagation은 chain rule의 재귀적인 응용입니다.
chiain rule에 의해 우리는 뒤에서부터 시작합니다.

00:07:49.182 --> 00:07:56.373
computational graph의 가장 끝,
우리는 뒤에서부터 gradient를 계산합니다.

00:07:56.373 --> 00:08:04.674
끝에서부터 시작해봅시다. 우리는 출력의 f에
대한 gradient를 계산하길 원합니다.

00:08:04.674 --> 00:08:08.591
그리고 이 gradient는 1입니다, 쉽죠.

00:08:10.065 --> 00:08:18.187
이번에는 뒤로 이동해서 z에 대한 gradient를 계산해봅시다.
여러분은 z에 대한 f의 미분이 q라는 것을 알고 있습니다.

00:08:19.993 --> 00:08:26.386
그리고 q의 값은 3이죠. 그래서 여기에서
z에 대한 f의 미분값은 3을 갖습니다.

00:08:28.819 --> 00:08:33.855
그리고 다음으로 q에 대한 f의 미분값을 알아봅시다.
값이 얼마일까요?

00:08:36.732 --> 00:08:37.957
q에 대한 f의 미분값은 얼마인가요?

00:08:37.957 --> 00:08:42.040
q에 대한 f의 미분값은 z와 같네요.

00:08:46.012 --> 00:08:54.130
그리고 z는 여기에서 -4입니다. 여기에서 우리는
q에 대한 f의 미분값이 -4라는 것을 알았습니다.

00:08:57.485 --> 00:09:03.793
자 이제 그래프의 뒤로 이동해봅시다.
여러분은 y에 대한 f의 미분값을 알고 싶습니다.

00:09:03.793 --> 00:09:08.986
하지만 여기에서 y는 f와 바로 연결되어 있지 않습니다.

00:09:08.986 --> 00:09:17.998
f는 z와 연결되어있습니다.
이것을 구하는 방법은 chain rule을 이용합니다.

00:09:17.998 --> 00:09:21.748
y에 대한 f의 미분은 q에 대한 f의 미분과
y에 대한 q의 미분의 곱으로 나타낼 수 있습니다.

00:09:22.746 --> 00:09:30.707
이것은 직관적으로 y가 f에 미치는
영향을 구하기 위한 것을 알수 있죠.

00:09:30.707 --> 00:09:37.416
실제로 이것은 우리가 q*f의 연산에서
q의 영향을 구할때와 동등합니다.

00:09:37.416 --> 00:09:45.497
q에 대한 f의 미분은 -4이고, q에 대한 y의
영향력 즉 y에 대한 q의 미분과 합성(곱)합니다.

00:09:46.604 --> 00:09:50.986
이 예제에서 y에 대한 q의 미분은 얼마인가요?

00:09:50.986 --> 00:09:51.819
[학생] 1

00:09:51.819 --> 00:09:52.980
맞아요. 정확합니다.

00:09:52.980 --> 00:09:55.916
y에 대한 q의 미분은 1이죠, 아시다시피.

00:09:55.916 --> 00:10:01.627
만약 우리가 y를 조금 변화시키면 q는
그것의 영향력 만큼 조금 변할것입니다.

00:10:01.627 --> 00:10:07.474
그리고 이것은 내가 y를 조금 바꿨을때 그것이 q에
대해 1만큼의 영향력을 미치는 것을 의미합니다.

00:10:07.474 --> 00:10:16.186
그리고 f에 대한 q의 영향력은 정확하게 -4의 입니다.

00:10:18.628 --> 00:10:26.470
이것들을 곱해보면 우리는 f에 대한 y의 영향력으로 -4를 얻습니다.
(1 곱하기 -4 이므로)

00:10:30.887 --> 00:10:41.191
만약 우리가 똑같이 x의 gradient를 알고싶다고 해봅시다. 여러분은
이전과 같은 방법으로 구할 수 있습니다. 어떻게 할 수 있을까요?

00:10:41.191 --> 00:10:42.711
[학생이 마이크로 대답하고 있다]

00:10:42.711 --> 00:10:44.746
들었습니다.

00:10:44.746 --> 00:10:51.051
정확합니다, 이 경우 우리는 다시한번 chain rule을 적용할 수 있습니다.

00:10:51.051 --> 00:10:55.882
우리는 f에 대한 q의 영향력이 -4인것을 알죠

00:10:55.882 --> 00:11:01.958
그리고 다시 우리는 같은 덧셈 노드를 가지고 있기
때문에 x에 대한 q의 영향력은 다시한번 1입니다.

00:11:01.958 --> 00:11:08.760
f에 대한 x의 gradient는 -4 * 1 이므로 -4입니다.

00:11:11.467 --> 00:11:15.389
지금 우리가 하고 있는 backpropagation에서 우리는
computational graph안에 모든 노드를 포함하고 있었습니다.

00:11:15.389 --> 00:11:20.724
하지만 각 노드는 오직 주변에 대해서만 알고 있습니다. 그렇죠?

00:11:20.724 --> 00:11:23.874
우리가 가지고 있는건 각 노드와 각 노드의 local 입력입니다.

00:11:23.874 --> 00:11:32.432
입력은 그 노드와 연결되어있고 값은 노드로 흘러들어가
이 노드로부터 출력을 얻게 됩니다.

00:11:32.432 --> 00:11:36.599
여기에서 local 입력은 x,y이고 출력은 z입니다.

00:11:39.777 --> 00:11:43.469
그리고 이 노드에서 우리는 local gradient를 구할 수 있습니다. 그렇죠?

00:11:43.469 --> 00:11:48.905
우리는 z에서 x에 대한 gradient를 구할 수 있으며 y에 대한 gradient도 마찬가지입니다.

00:11:48.905 --> 00:11:51.217
그리고 이것들은 대부분 간단한 연산입니다. 그렇죠?

00:11:51.217 --> 00:11:54.821
각 노드는 우리가 이전에 보았던 것처럼 덧셈 혹은 곱셈입니다.

00:11:54.821 --> 00:12:04.665
 그것들은 쉽게 gradient를 구할 수 있고, 우리는
그것을 찾기 위해 복잡한 미적분을 할 필요가 없습니다.

00:12:04.665 --> 00:12:15.313
[학생] 이전으로 돌아가서 설명해 주실수 있으십니까? 어떻게
마지막 슬라이드에서 이 기본적인 미적분으로 넘어왔는지..

00:12:15.313 --> 00:12:18.683
네, 다시 돌아가보죠

00:12:18.683 --> 00:12:20.183
잠시만요..

00:12:21.740 --> 00:12:26.565
여기로 돌아와보면 우리는 미적분학만을 사용해 모든 것을 쓸 수 있습니다.

00:12:26.565 --> 00:12:32.572
아시다시피 우리는 x에 대한 f의 미분을 알고 싶었고 우리는 이 식을 사용해서 표현했습니다.

00:12:32.572 --> 00:12:42.667
그리고 보시면 이것은 z입니다. 이것은 단순합니다
하지만 정말로 복잡한 표현을 보게 된다면

00:12:42.667 --> 00:12:47.487
당신은 무언가의 gradient를
유도하기위해 미적분을 쓰기 싫을 것입니다.

00:12:47.487 --> 00:12:52.094
 대신 만약 당신이 이 식을 사용하게 되면

00:12:52.094 --> 00:13:01.612
당신은 계산 노드를 나눌 수 있으며 이는 gradient를 구하기 위해 아주 단순한 계산만을 사용합니다.

00:13:01.612 --> 00:13:10.038
알다시피 덧셈, 곱셈, 지수 같은 것들은 원하는 만큼 단순하고
이 모든 것들을 곱하기 위해 chain rule만 있으면 됩니다.

00:13:10.038 --> 00:13:16.571
그러면 gradient를 구할 수 있습니다. 필요한 다른 식은 없습니다.

00:13:18.562 --> 00:13:20.508
이해가 되셨나요?

00:13:20.508 --> 00:13:21.367
[학생: 웅성웅성]

00:13:21.367 --> 00:13:25.034
나중에 이것에 대한 예제를 보겠습니다.

00:13:28.751 --> 00:13:30.449
또 다른 질문이 있었습니까?

00:13:30.449 --> 00:13:32.240
[학생이 마이크로 말하고 있다]

00:13:32.240 --> 00:13:36.146
[학생] z가 나타내는 -4는 무엇입니까?

00:13:36.146 --> 00:13:38.408
음.. 네 -4는

00:13:38.408 --> 00:13:43.831
위의 초록색 값은 function을 통해 전달되는 값입니다. 그렇죠?

00:13:43.831 --> 00:13:49.835
 여기에서 x는 -2, y는 5이고, z는 -4입니다.

00:13:49.835 --> 00:13:55.621
 그리고 우리가 원하는 계산된 다른 값들을 채웠습니다.

00:13:55.621 --> 00:14:09.289
 우리는 q를 x+y라고 할 수 있습니다.
이것은 -2 + 5이기 때문에 3이 될 것이고 z는 -4죠

00:14:09.289 --> 00:14:16.886
최종 값 f는 z와 q를 곱해서 얻을 수 있고 그것은 -4 * 3입니다. 그렇죠?

00:14:16.886 --> 00:14:23.790
그리고 아래에 있는 붉은색 값은 gradient에 대해서 적어놓은 것입니다.
우리가 뒤에서부터 계산한.

00:14:29.418 --> 00:14:38.969
그래요 우리가 말했던 것처럼 우리가 가지고 있는 각 노드는 local 입력을 받고

00:14:38.969 --> 00:14:46.302
보이는 것처럼 다음 노드로 출력값을 보냅니다.
그리고 우리가 계산한 local gradient가 있는데

00:14:46.302 --> 00:14:51.175
이는 들어오는 입력에 대한 출력의 기울기입니다.

00:14:51.175 --> 00:14:55.155
backpropagation이 어떻게 동작하는지 알아봅시다.

00:14:55.155 --> 00:14:56.750
우리는 그래프의 뒤에서 부터 시작합니다.

00:14:56.750 --> 00:14:58.471
뒤에서부터 시작 부분까지 끝까지 진행됩니다.

00:14:58.471 --> 00:15:08.980
각 노드에 도달하면 출력과 관련한 노드의
gradient가 상류의(입력과 가까운) 노드로 전파됩니다.

00:15:08.980 --> 00:15:17.808
그래서 우리는 backpropagation에서 이 노드에 도달할 때까지
z에 대한 최종 loss L은 이미 계산되어있습니다. 그렇죠?

00:15:17.808 --> 00:15:26.675
이제 우리는 x와 y의 값에 대한 바로 직전 노드의 gradient를 찾고자합니다.

00:15:27.679 --> 00:15:33.053
그리고 우리가 이미 보았듯이, 우리는 chain rule을 사용합니다.

00:15:34.857 --> 00:15:44.987
x의 gradient는 z에 대한 gradient와, x에 대한 z의 local gradient로 합성됩니다.

00:15:44.987 --> 00:15:48.422
그렇습니다. chain rule에서는 항상 위쪽으로 gradient가 전파됩니다.

00:15:48.422 --> 00:15:55.071
그리고 이것(gradient)을 local gradient와 곱해서 (노드의)입력에 대한 gradient를 구합니다.

00:15:55.071 --> 00:16:01.949
[학생] 죄송하지만 이 방법은 gradient를 구하는 상징적인 예시일 뿐이지
실제 gradient를 계산하는 일반적인 수식이 아닌것 같습니다.

00:16:01.949 --> 00:16:11.896
[학생] 이 방법은 그때그때의 값에 따라서만 동작합니다.
콜록콜록, 또는 약간의 상수 값과 함께요.

00:16:11.896 --> 00:16:22.579
질문은 이 방법이 현재 값의 여부와 관계없이 동작하는지에 관한 것이죠?

00:16:23.842 --> 00:16:29.819
우리가 연결했던 함수에 현재 값이 주어지면
우리는 이것에 대해 변수에 관한 식으로 나타낼 수 있습니다. 그렇죠?

00:16:29.819 --> 00:16:36.357
z에 대한 L의 gradient를 보면 이것은 식으로 나타나 있고,

00:16:36.357 --> 00:16:48.708
x에 관한 z의 gradient를 보면 이것은 또 다른 수식입니다 그렇죠?
우리가 이것들에 값을 대입하여 x에 대한 gradient를 얻습니다.

00:16:48.708 --> 00:16:55.203
당신이 할 수 있는 것은 이 모든 식을 재귀적으로 사용할 수 있다는 것입니다. 맞죠?

00:16:55.203 --> 00:17:01.442
z에 대한 gradient, 그리고 x에 대한 gradient 이것들은 단순한 수식으로 나타납니다.

00:17:01.442 --> 00:17:08.612
만약 우리가 곱셈 노드를 가지고 있다고 가정하면 이 경우 x에 대한 z의 gradient는 y가 될 것입니다.

00:17:08.612 --> 00:17:12.811
하지만 z에 대한 L의 gradient는 이 그래프 내에서 아주 복잡한 부분입니다.

00:17:12.811 --> 00:17:20.748
그렇기 때문에 여기에서 우리는 이 숫자들만 가지고 합니다.

00:17:20.748 --> 00:17:30.719
학생이 말했던 것처럼, 이것은 값이 전달되는 기본적인 부분입니다.
우리는 그것을 수식에 따라 곱하고 local gradient를 갖습니다.

00:17:30.719 --> 00:17:35.647
나는 이 방식이 더 몇몇 슬라이드의 복잡한 예제보다 명확하다고 생각합니다.

00:17:38.225 --> 00:17:44.284
그래서 지금 y에 대한 L의 gradient는 다시 한번 완전히 같은 방식입니다.

00:17:44.284 --> 00:17:54.411
chain rule을 사용해서, z에 대한 L의 gradient와 그리고 y에 대한 z의 gradient를 서로 곱합니다.
chain rule에 의해 이 둘의 곱은 원하는 gradient를 줍니다.

00:17:55.848 --> 00:18:00.816
그리고 나서 우리가 gradient를 구하면 이 노드와 연결된 직전 노드로 전달할 수 있습니다.

00:18:00.816 --> 00:18:09.047
이것으로부터 얻을 수 있는 중요한 것은
각 노드는 우리가 계산한 local gradient를 가지고 있습니다.

00:18:09.047 --> 00:18:16.127
우리는 backpropagation을 통해 그것을 얻습니다.
값들은 상위 노드 방향으로 계속 전달되고

00:18:16.127 --> 00:18:20.077
우리는 이것을 받아 local gradient와 곱하기만 하면 됩니다.

00:18:20.077 --> 00:18:31.664
우리는 노드와 연결된 노드 이외의 다른 어떤 값에 대하여 신경쓰지 않아도 됩니다.

00:18:31.664 --> 00:18:35.353
이제부터는 다른 예제에 대해서 살펴보겠습니다. 이것은 이전보다는 조금 복잡합니다.

00:18:35.353 --> 00:18:39.239
그렇기 때문에 backpropagation이 얼마나 유용한 방식인지를 알게 될 것입니다.

00:18:39.239 --> 00:18:49.576
이 경우 함수 w,x에 대한 함수 f는 1 / e^ - (w0x0 + w1x1 + w2)와 같습니다.

00:18:52.619 --> 00:18:57.525
다시 말하지만 첫 번째 과정은 이것을 computational graph로 나타내는 것입니다.

00:18:57.525 --> 00:19:02.863
이 경우의 graph를 볼 수 있습니다.
먼저 우리는 w와 x를 곱합니다. x0과 x0, x1과 x1 그리고

00:19:02.863 --> 00:19:10.388
w2와는 이것들을 모두 더하게됩니다. 그렇죠?

00:19:10.388 --> 00:19:20.318
그리고 이것에 -1을 곱하고 exponential을 취하고, 1을 더합니다.
마지막으로 모든 term을 역수로 뒤집습니다. (1/x)

00:19:22.533 --> 00:19:25.170
여기서도 값을 채워 놓았습니다.

00:19:25.170 --> 00:19:35.171
우리에게 ws와 xs가 주어졌다고 했을때, 우리는 값을 이용해 모든
단계마다 계산을 통해서 앞으로(오른쪽 방향으로) 진행할 수 있습니다.

00:19:37.091 --> 00:19:44.427
그리고 아래에다가 나중에 도움이 될 몇몇 유도식을 적어놓았습니다.

00:19:44.427 --> 00:19:49.339
이전에 단순한 예제에서 했던 것과 같이

00:19:49.339 --> 00:19:51.820
backpropagation을 진행할 것입니다.

00:19:51.820 --> 00:19:53.327
다시한번 그래프의 뒤에서부터 시작합니다.

00:19:53.327 --> 00:20:00.736
그리고 여기에서 최종 변수에 대한 출력의 gradient는 1입니다.

00:20:04.074 --> 00:20:13.405
이제 뒤로 한 스텝 가봅시다.
1/x 이전의 input에 대한 gradient는 얼마입니까?

00:20:13.405 --> 00:20:21.592
음.. 이 경우 우리는 upstream gradient를 알고 있습니다.
빨간색으로 쓰여있는 1입니다. 그렇죠?

00:20:21.592 --> 00:20:30.181
이것은 흐름에 따라 전파되는 gradient입니다. 이제 local gradient를 찾아야 합니다.
이 노드(1/x)에 대한 local gradient입니다.

00:20:30.181 --> 00:20:39.935
우리가 가지고 있는 f는 1/x 이고, 이것의 local gradient인
x에 대한 f의 미분은 -1/x^2와 같습니다. (빨간 박스 참고)

00:20:39.935 --> 00:20:45.845
그래서 여기에서 우리는 -1/x^2를 얻습니다.
그리고 x에 값을 대입합니다.

00:20:45.845 --> 00:20:57.075
이것(x)은 1.37이고,이 변수에 대한 우리의 최종 gradient는
1/-1.37^2 * 1 = -0.53과 같습니다.

00:21:04.382 --> 00:21:06.769
다음 노드로 다시 이동해봅시다.

00:21:06.769 --> 00:21:09.023
우리는 똑같은 과정을 거치게 될 것입니다, 맞습니까?

00:21:09.023 --> 00:21:16.007
여기에서 upstream gradient는 -0.53입니다. 그렇죠?

00:21:16.007 --> 00:21:20.365
그리고 현재 노드는 +1입니다.

00:21:20.365 --> 00:21:25.203
아래의 유도식을 다시 살펴보겠습니다.

00:21:25.203 --> 00:21:31.729
(x+상수)에 대한 local gradient는 1입니다. 그렇죠?

00:21:31.729 --> 00:21:37.376
이제 chain rule을 이용하면 이 변수에 대한 gradient는 얼마입니까?

00:21:42.883 --> 00:21:51.592
upstream gradient는 -0.53이고, 우리의 local gradient는 1입니다.
그렇기 때문에 (gradient 는) -0.53이 됩니다.

00:21:55.849 --> 00:21:59.604
한 단계 더 진행해봅시다.

00:21:59.604 --> 00:22:05.022
여기에서 우리는 exponential을 가지고 있습니다.
upstream gradient는 얼마입니까?

00:22:05.022 --> 00:22:08.536
[학생이 마이크로 말하고 있다]

00:22:08.536 --> 00:22:11.775
네, upstream gradient는 -0.53이죠.

00:22:11.775 --> 00:22:18.002
여기에서 local gradient는 얼마일까요?
이것은 x에 대한 e의 local gradient가 될 것입니다.

00:22:18.002 --> 00:22:28.301
exponential 노드에서, chain rule에 의해 gradient가 -0.53*e^x임을 알 수 있습니다.

00:22:30.869 --> 00:22:37.587
(x의) 값이 -1인 경우 (exponential 노드에서) 최종 gradient는 -0.2가 됩니다.

00:22:40.215 --> 00:22:47.560
좋아요, 노드가 하나 더 있습니다.
다음 노드는 -1과 곱하는 노드입니다. 그렇죠?

00:22:48.912 --> 00:22:52.729
여기에서 upstream gradient는 얼마인가요?

00:22:52.729 --> 00:22:54.090
[학생] -0.2

00:22:54.090 --> 00:22:56.565
네 맞아요, 그리고 local gradient는 무엇이 될까요

00:22:56.565 --> 00:23:01.510
유도식을 한번 살펴 보세요.

00:23:01.510 --> 00:23:03.049
얼마인가요?

00:23:03.049 --> 00:23:03.889
들은것 같네요.

00:23:03.889 --> 00:23:05.205
[학생] -1

00:23:05.205 --> 00:23:09.680
네 -1 맞아요.

00:23:09.680 --> 00:23:19.220
local gradient는 x에 대한 f의 미분입니다.
그러므로 이 노드의 결과는 -1이 됩니다. (1 * -1이 되므로)

00:23:19.220 --> 00:23:26.825
그렇기 때문에 gradient는 -1 * -0.2이므로 0.2가 됩니다.

00:23:29.169 --> 00:23:37.269
좋아, 이제 우리는 덧셈 노드에 도달했습니다.
그리고 여기에서 우리는 두 개의 노드와 연결됩니다.

00:23:37.269 --> 00:23:43.286
일단 여기에서 upstream gradient는 얼마인가요?
그것은 0.2일거에요, 그리고

00:23:43.286 --> 00:23:50.122
각 브랜치에 대한 gradient를 추가해봅시다.

00:23:50.122 --> 00:23:56.226
이전의 간단한 예제에서 덧셈 노드를 가지고 있을 때 덧셈 노드에서,
각 입력에 대한 local gradient는 1이었습니다.

00:23:56.226 --> 00:24:06.406
여기에서 local gradient는 upstream gradient 0.2와
한번 곱해질 것입니다. 맞죠? 1 * 0.2 = 0.2입니다.

00:24:06.406 --> 00:24:16.957
그리고 우리는 아래(bottom) 브랜치에 대해서도 똑같이 할 것입니다.
같은 들어오는 gradient 0.2를 이용해서

00:24:18.400 --> 00:24:23.277
그리고 총 gradient는 0.2입니다.
여기까지 이해가 되시나요?

00:24:23.277 --> 00:24:26.110
좋아요.

00:24:27.581 --> 00:24:35.413
몇가지 gradient를 더 채워봅시다.
w₀과 x₀이 있는곳까지 가면 여기에서는 곱셈 노드를 가지고 있습니다.

00:24:37.648 --> 00:24:45.698
이전에 보았던 곱셈 노드에서 input에 대한 gradient는
한 인풋에 대하여 다른 인풋의 값이었습니다.

00:24:45.698 --> 00:24:49.506
이 경우 w₀에 대한 gradient는 얼마일까요?

00:24:56.927 --> 00:24:58.795
[학생] -0.2

00:24:58.795 --> 00:25:04.366
네 -0.2 맞습니다.
w0의 관점에서 upstream gradient 0.2를 가지고 있죠.

00:25:04.366 --> 00:25:11.900
아래에 있는 다른 하나(x0)는 -1이기 때문에
-1과 0.2를 곱해 -0.2를 얻게 됩니다.

00:25:13.781 --> 00:25:22.008
x0에 대해서도 같은 과정을 반복하면 0.2 * 2를 하게 되므로 0.4를 얻게 됩니다.

00:25:22.008 --> 00:25:24.425
모든 gradient를 채워 넣었습니다.

00:25:26.525 --> 00:25:30.692
그리고 이전에 질문 중에 왜 이 방식이 특정 변수에 대해서

00:25:32.200 --> 00:25:43.071
analytic gradient를 유도해 값을 계산하는 것보다 단순한지가 있었습니다.

00:25:43.071 --> 00:25:50.164
우리가 써야만 하는 local gradient에 대한 표현을 여기에서 볼 수 있습니다.

00:25:50.164 --> 00:25:54.034
 우리가 가진 각각의 값을 결합했습니다.

00:25:54.034 --> 00:26:01.532
곱셈으로 나타내기 위해 chain rule을 사용했고 뒤에서부터
시작하여 모든 변수에 대한 gradients를 구했습니다.

00:26:01.532 --> 00:26:11.644
그리고 우리는 w0과 x0에 대한 gradient 또한 같은 방법을 사용해 구했습니다.

00:26:14.490 --> 00:26:21.996
그리고 주목하기 바라는 것은 우리가 computational graph를 만들 때,
computational 노드에 대해 우리가 원하는 세분화된 정의를 할 수 있는 것입니다.

00:26:21.996 --> 00:26:29.813
우리는 이번 케이스에서 덧셈과 곱셈, 절대적으로 작은 단위로 쪼갰습니다.
알다시피 덧셈과 곱셈은 더 단순해질 수 없습니다.

00:26:29.813 --> 00:26:38.883
 실제로 원한다면 이 노드들을 더
복잡한 그룹으로 묶을 수 있습니다.

00:26:38.883 --> 00:26:44.600
우리는 그 노드에 대한 local gradient를 적어두기만 하면 됩니다.

00:26:44.600 --> 00:26:53.950
예를 들어 sigmoid 함수를 보겠습니다.
sigmoid 함수에 대한 정의를 오른쪽 상단에 적어놓았습니다.

00:26:55.691 --> 00:27:03.404
이는 1 / (1 + e^-x)와 같습니다.
그리고 이것은 남은 수업에서 많이 보게 될 함수입니다.

00:27:03.404 --> 00:27:12.686
그리고 우리는 이것에 대한 gradient를 계산할 수 있습니다.
우리는 이것을 사용할 수 있으며, 분석적으로 이를 살펴본다면

00:27:12.686 --> 00:27:16.427
마지막에 좋은 표현을 얻을 수 있습니다.

00:27:16.427 --> 00:27:26.609
따라서 이 예제에서 이것은 (1- sigma(x)) * sigma(x)와 같습니다.

00:27:26.609 --> 00:27:33.210
그리고 이 경우에 우리는 sigmoid를 만들기 위한 모든 계산을 그래프에 가지고 있습니다.

00:27:33.210 --> 00:27:37.038
그리고 우리는 이것을 하나의 big 노드, sigmoid로 바꿀 수 있습니다.

00:27:37.038 --> 00:27:43.655
우리는 이 gate의 local gradient, expression
그리고 x에 대한 sigmoid의 미분을 알고 있기 때문이죠. 그렇죠?

00:27:43.655 --> 00:27:54.795
여기에서 가장 중요한 사실은 local gradient를 적을
수 있는한 더 복잡한 노드 그룹을 만들 수 있다는 것입니다.

00:27:54.795 --> 00:28:01.645
 그리고 이 모든것은 trade-off의 관계에 있습니다.

00:28:01.645 --> 00:28:06.433
간결하고 단순한 그래프를 얻기 위해 당신이 많은 수학을 알고 싶어하는 것과

00:28:06.433 --> 00:28:13.793
각 노드에서 단순한 gradient를 얻고 싶어하는 것 사이에서.

00:28:14.913 --> 00:28:19.290
그 결과 당신은 원하는 만큼 복잡한 computational graph를 쓸 수 있습니다.

00:28:19.290 --> 00:28:21.616
질문 있나요?

00:28:21.616 --> 00:28:28.149
[학생] 이것은 그래프 자체에 대한 질문입니다. 처음의 두 곱셈 노드의 weight들은 덧셈 노드와 연결되어 있지 않습니다.
특별한 이유가 있습니까? (y = wx + b의 느낌으로 질문을 한 듯)

00:28:28.149 --> 00:28:36.771
그것들은 하나의 덧셈 노드와 연결되어야 할 것 같은데 질문은
왜 w0와 x0이 w2와 연결이 되어 있지 않냐는 것이죠?

00:28:36.771 --> 00:28:46.179
 모든 추가 노드들은 서로 연결되어 있기 때문에 제 대답은
당신이 원한다면 그렇게 할 수 있다는 것입니다.

00:28:46.179 --> 00:28:50.479
그리고 실제로 당신은 그것을 원할수도 있습니다.
그것은 매우 단순한 노드이기 때문에.

00:28:50.479 --> 00:28:52.821
그래서 이 경우 저는 최대한 단순하게 썼습니다.

00:28:52.821 --> 00:29:04.499
각 노드는 오직 2개의 입력만 받게, 하지만 당신은 분명 그것을 할 수 있습니다.
이 질문에 대한 다른 질문이 있으십니까?

00:29:04.499 --> 00:29:13.806
computational graph로 생각하는 것은 저를 아주 편안하게 만듭니다.
gradient를 구할때나 다른 무언가의 gradient를 찾아야만 할 때,

00:29:15.406 --> 00:29:22.960
sigmoid 처럼 설사사 그 식이 정말로 복잡하고, 두려워도

00:29:22.960 --> 00:29:33.214
우리가 알다시피 필요하다면 이것을 유도해냈습니다.
computational graph의 관점에서 나는 적어나갔고

00:29:33.214 --> 00:29:44.058
나는 단순하게 진행할 수 있었다. backpropagation과 chain rule을 통해.
그리고 나는 필요한 gradient를 계산할 수 있었다.

00:29:44.058 --> 00:29:53.438
그리고 이것은 당신이 과제를 할 때 생각해야 합니다.
gradient를 찾기 어려울 때 언제든지 이 방식을 사용해서 알아낼 수 있습니다.

00:29:53.438 --> 00:29:57.285
모든 부분들을 쪼개고 chain rule을 적용할 수 있습니다.

00:29:57.285 --> 00:30:09.292
아시다시피 우리는 이 노드들을 sigmoid로 그룹화 하는 것을 보았습니다.
실제로 이것이 동등한지 확인했습니다.

00:30:10.558 --> 00:30:21.717
우리는 이것을 연결할 수 있습니다.
그러면 우리는 입력이 1 (초록색으로 쓰여 있음) 출력은 0.73을 갖습니다. 그렇죠?

00:30:21.717 --> 00:30:25.800
이것은 sigmoid 함수에 연결하면 될 것입니다.

00:30:26.745 --> 00:30:36.315
 그리고 gradient를 얻기 원한다면 하나의 완전한 sigmoid 노드를 이용할 수 있습니다.

00:30:36.315 --> 00:30:41.219
앞에서 이것의 local gradient를 유도했었습니다. 그렇죠?

00:30:41.219 --> 00:30:45.962
그것은 (1-sigmoid(x)) * sigmoid(x) 였죠.
즉 이것을 여기에 대입해봅시다.

00:30:45.962 --> 00:30:57.543
알고있는 값은 x는 0.73이고 이 값을 위의 식에
대입하면 gradient로 0.2를 얻게 됩니다.

00:30:57.543 --> 00:31:09.267
우리는 이것을 upstream gradient인 1과 곱합니다. 그러면 우리는 sigmoid
gate로 바꾸기 이전의 작은 노드들로 계산된 값과 정확히 같은 값을 얻을 수 있습니다.

00:31:09.267 --> 00:31:19.957
좋아요, 우리가 gradient를 뒤에서부터 가져오는 동안 이제 어떤 일이 일어나는지 봅시다.

00:31:23.714 --> 00:31:28.790
직관적 해석으로 알 수 있는 패턴이 있습니다.

00:31:28.790 --> 00:31:37.214
 덧셈 게이트는 gradient를 나눠줍니다.

00:31:37.214 --> 00:31:48.586
두 개의 브랜치와 연결되는 덧셈 게이트에서는 upstream
gradient를 연결된 브랜치에 정확히 같은 값으로 나눠줍니다.

00:31:48.586 --> 00:31:55.156
여기에는 생각해볼만한 것이 더 있습니다.
그렇다면 max 게이트 모양은 어떤 모양입니까?

00:31:55.156 --> 00:32:03.350
아래에 max 게이트가 있습니다.
입력으로 z와 w가 들어오고 z는 2, w는 -1입니다.

00:32:04.825 --> 00:32:11.444
그리고 최대값을 취한 다음에 그것을 통과시킵니다.

00:32:11.444 --> 00:32:20.068
이것에 대한 gradient를 구해보면, upstream gradient는 2네요 그렇죠.

00:32:20.068 --> 00:32:26.890
이 것(max 노드)의 local gradient는 무엇일까요?

00:32:30.057 --> 00:32:31.753
[학생] 하나는 0이되고 다른 하나는

00:32:31.753 --> 00:32:35.011
맞습니다.

00:32:35.011 --> 00:32:35.862
[학생이 마이크로 말하고 있다]

00:32:35.862 --> 00:32:45.873
맞습니다. z는 gradient 2를 가질 것이고
w는 gradient 0을 가질 것입니다.

00:32:45.873 --> 00:32:50.931
이것은 gradient가 단지 통과하는 효과입니다.

00:32:50.931 --> 00:32:57.140
하나는 전체 값이, 다른 하나에는 0의 gradient가 향하게 됩니다.

00:32:57.140 --> 00:33:04.844
우리는 이런 종류의 gradient 라우터에 대해 생각할 수 있습니다.
덧셈 노드에서는 같은 gradient를 들어오는 브랜치에게 전달해주기 때문에

00:33:05.949 --> 00:33:12.630
max 게이트는 그것을 받고 하나의 브랜치를 지정합니다.
그리고 이것은 forward pass를 볼 때 의미가 있습니다.

00:33:12.630 --> 00:33:19.393
값(value)은 무슨일이 일어날까요. 최대값이 남은 computational graph로 통과됩니다.

00:33:19.393 --> 00:33:27.647
그래서 결국 함수 계산에 실제로 영향을 주는 값은 유일한 값이므로

00:33:27.647 --> 00:33:32.610
따라서 gradient를 다시 전달할 때

00:33:33.544 --> 00:33:40.705
무엇을 조정하고 계산의 해당 지점을 통해 흐르게 하는 것이 바람직합니다.

00:33:40.705 --> 00:33:44.872
[학생이 마이크로 말하고 있다]

00:33:46.028 --> 00:33:56.627
네 답은 local gradient는 기본적으로 다른 변수의 값입니다.

00:33:59.408 --> 00:34:01.407
네 정확합니다.

00:34:01.407 --> 00:34:06.409
그래서 이것을 gradient switcher라고 생각할 수 있습니다.
맞습니까? Switcher, 저는 scaler라고 추측합니다.

00:34:06.409 --> 00:34:15.788
upstream gradient를 받아 다른 브랜치의 값으로 scaling 합니다.
네 그리고 다른 주목할만한 것은 우리가 여러 노드와 연결되어 있는 하나의 노드를 가지고 있을 때

00:34:20.205 --> 00:34:22.592
gradient는 이 노드에서 합산됩니다. 맞습니까?

00:34:22.592 --> 00:34:31.520
다 변수(multivariate) chain rule을 사용하는 노드들에서 우리는
단지 각 노드들로부터 들어오는 upstream gradient 값을 취하고

00:34:31.520 --> 00:34:35.274
그리고 이것들을 합합니다.

00:34:35.274 --> 00:34:43.004
그러면 당신은 이것들로부터 다 변수 chain rule을 볼 수 있습니다.
그리고 이것에 대해 생각해보세요,

00:34:43.005 --> 00:34:54.948
만약 당신이 이 노드를 조금 변경시킨다면
그래프를 따라 forward pass를 할 때 연결된 노드들에게 영향을 미칠 것입니다.

00:34:54.949 --> 00:35:03.803
그리고 당신이 backpropagation을 할 때 이 두개의
gradient가 돌아오면 이 노드에 영향을 미치게 될 것입니다.

00:35:03.803 --> 00:35:07.872
따라서 이 값을 더해야 총 upstream gradient가 됩니다.

00:35:07.872 --> 00:35:12.725
backpropagation에 대한 질문이 있습니까?

00:35:18.439 --> 00:35:23.429
[학생] 우리는 실제 가중치에 대해 아무런 업데이트도 하지 않았습니다.

00:35:23.429 --> 00:35:25.490
[마이크로 말하는 중]

00:35:25.490 --> 00:35:31.418
네 질문은 우리는 아직 이 가중치 값에 대해서 아무런 업데이트를 하지 않았다는 것입니다.

00:35:31.418 --> 00:35:35.994
우리는 변수에 대한 gradient만 찾았습니다. 맞습니다.

00:35:35.994 --> 00:35:41.206
이 강의에서 이야기 한 것은 어떻게 함수에서 변수에 대한 gradient를 찾는가였습니다.

00:35:41.206 --> 00:35:48.210
찾은 다음 마지막 최적화 강의에서 배운 모든 것을 적용할 수 있습니다.

00:35:51.258 --> 00:35:57.363
그래서 gradient가 주어지면, 우리는 가중치를 업데이트하기 위한 다음 스텝을 밟습니다.

00:35:57.363 --> 00:36:04.331
 당신은 이 모든 구조를 우리가 마지막
최적화강의에서 배운 것에 적용할 수 있습니다.

00:36:04.331 --> 00:36:11.196
여기에서 우리가 한 것은 임의의 복잡한 함수에 대해 gradient를 계산하는 것을 배운 것입니다.

00:36:11.196 --> 00:36:20.039
따라서 나중에 신경망과 같은 복잡한 함수에 대해 이야기 할 때 유용할 수 있습니다.

00:36:20.039 --> 00:36:24.453
[학생] 모든 변이에 대해서 적어 주실 수 있습니까?
이 슬라이드를 이해하는데 도움이 되기 위해

00:36:24.453 --> 00:36:31.069
그래요 저는 이것을 보드에 쓸 수 있습니다.

00:36:32.851 --> 00:36:39.544
만약 우리가 함수 f의 x에 대한 gradient를 가지고 있으면

00:36:39.544 --> 00:36:45.821
 변수 i에 의해 연결되어있다고 가정해 보겠습니다.

00:36:49.203 --> 00:37:03.311
 x는 여러 요소들과 연결되어 있다고 할 수 있습니다.

00:37:03.311 --> 00:37:15.217
이 경우에는 ∂qi이고, 그리고 chain rule은 모든것을
취하고 있으며 각각의 중간 변수의 효과를 취할 것입니다.

00:37:16.453 --> 00:37:26.447
우리의 최종 출력 f, 그리고 다음 변수 x가 해당 중간 값에 미치는 영향에 대해.

00:37:29.127 --> 00:37:39.742
이것은 기본적으로 모든 것들을 합쳐 놓은 것입니다.
좋아요, 이제 우리는 스칼라 값에 대한 모든 예제를 완료했습니다.

00:37:42.203 --> 00:37:50.250
이제 벡터가있을 때 어떻게 될까요?
우리의 변수 x,y,z에 대해서 숫자 대신에 vector를 가지고 있다고 합시다.

00:37:50.250 --> 00:37:59.428
모든 흐름은 정확히 같습니다.
차이점이라면 우리의 gradient는 Jacobian 행렬이 될 것입니다.

00:37:59.428 --> 00:38:10.574
그래서 이것들은 각 요소의 미분을 포함하는 행렬이 될 것입니다.
예를들어 x의 각 원소에 대해 z에 대한 미분을 포함하는.

00:38:14.237 --> 00:38:24.049
좋아요, 예제를 하나 봅시다.
우리의 입력은 4096차원의 벡터입니다.

00:38:24.049 --> 00:38:29.797
그리고 이것은 CNN에서 흔히 볼 수 있는 사이즈입니다.

00:38:29.797 --> 00:38:37.918
 그리고 이 노드는 요소별로(elementwise) 최대값을 취합니다.

00:38:37.918 --> 00:38:45.295
우리는 f를 가지고 있습니다.
요소별로 0과 비교해 최대 값을 같는 x를 취하는,

00:38:46.875 --> 00:38:54.052
그리고 출력 또한 4096 차원의 벡터입니다.
좋아요, 이 경우에 Jacobian 행렬의 사이즈는 얼마인가요?

00:38:56.969 --> 00:39:10.396
이전에 말했던 것을 기억해보세요
Jacobian 행렬의 각 행은 입력에 대한 출력의 편미분이 될 것입니다.

00:39:11.705 --> 00:39:17.572
제가 들은 답은 4096의 제곱인데요 맞습니다.

00:39:17.572 --> 00:39:21.405
그리고 4096*4096은 매우 큽니다.

00:39:22.261 --> 00:39:25.203
그리고 실질적으로 이것은 더 커질 수 있습니다.

00:39:25.203 --> 00:39:30.692
예로들면 100개의 인풋을 동시에 입력으로 같는 배치를 이용해 작업할 수 있습니다.

00:39:30.692 --> 00:39:38.739
그것은 우리의 노드를 더욱 효율적으로 만들지만 그것은 100배 커지게 만듭니다.

00:39:38.739 --> 00:39:45.082
실제로 Jacobian은 4096000 * 4096000입니다.

00:39:45.082 --> 00:39:50.750
이것은 너무 거대해서 작업에 실용적이지 않습니다.

00:39:50.750 --> 00:39:57.507
실제로는, 우리는 이 거대한 Jacobian을 계산할 필요가 없습니다.

00:39:57.507 --> 00:40:00.902
그러면 이 Jacobian 행렬이 어떻게 생겨나게 되었을까요?

00:40:00.902 --> 00:40:04.509
만약 우리가 요소별로 최대값을 같는 여기에서 어떤 일이 일어나는지 생각해 본다면

00:40:04.509 --> 00:40:08.312
 우리는 각각의 편미분에 대해 생각해볼 수 있습니다.

00:40:08.312 --> 00:40:13.888
 입력의 어떤 차원이 출력의 어떤 차원에 영향을 줍니까?

00:40:13.888 --> 00:40:19.686
 이 Jacobian 행렬에서 어떤
종류의 구조를 볼 수 있습니까?

00:40:19.686 --> 00:40:21.198
[학생 대답 중]

00:40:21.198 --> 00:40:23.869
네 들었습니다. 대각선, 정확합니다.

00:40:23.869 --> 00:40:27.703
이것은 요소별 이기 때문에, 입력의 각 요소, 첫번째 차원은

00:40:27.703 --> 00:40:31.109
오직 출력의 해당 요소에만 영향을 줍니다.

00:40:31.109 --> 00:40:38.014
 그렇기 때문에 우리의 Jacobian
행렬은 대각행렬이 될 것입니다.

00:40:38.014 --> 00:40:47.198
 실제로 이 전체 Jacobian 행렬을 작성하고 공식화 할 필요는 없습니다.

00:40:47.198 --> 00:40:51.365
우리는 출력에 대한 x의 영향에 대해서 그리고 이 값을 사용하는 것에 대해서만 알면 됩니다.

00:40:54.986 --> 00:41:01.800
 그리고 우리가 계산한 gradient의
값을 채워 넣으면 됩니다.

00:41:04.100 --> 00:41:06.716
좋아요, 이제 computational graph보다 구체적인 벡터화 된 예제를 보겠습니다.

00:41:06.716 --> 00:41:11.724
 보겠습니다. x와 W에 대한 함수 f는

00:41:11.724 --> 00:41:19.232
 x에 의해 곱해진 W의 L2와 같습니다.

00:41:22.407 --> 00:41:26.763
그리고 이 경우 x를 n-차원이라고
하고, W는 n*n이라고 합시다.

00:41:29.076 --> 00:41:30.563
네 처음부터 해 봅시다.

00:41:30.563 --> 00:41:32.635
computational graph 쓰기.. 맞죠?

00:41:32.635 --> 00:41:35.303
우리는 x에 의해 곱해진 W를 가지고 있고

00:41:35.303 --> 00:41:37.886
그리고 L2가 뒤따릅니다.

00:41:39.520 --> 00:41:42.822
이제 값을 채워 넣읍시다.

00:41:42.822 --> 00:41:45.382
W는 2x2 행렬인 것을 볼 수 있고

00:41:45.382 --> 00:41:47.560
x는 2차원의 벡터입니다. 맞죠?

00:41:47.560 --> 00:41:53.949
 우리는 중간 노드를 다시 쓸 수 있습니다.

00:41:53.949 --> 00:41:56.653
그것은 q로 할 것이고, W와 x의 곱입니다.

00:41:56.653 --> 00:42:02.666
 이것은 요소별 방식으로 쓸 수 있습니다.

00:42:02.666 --> 00:42:05.632
W1,1 * x1 + W1,2 * x2 등등

00:42:05.632 --> 00:42:12.611
그러면 우리는 이제 f를 q에 대한 표현으로 나타낼 수 있습니다. 맞죠?

00:42:12.611 --> 00:42:15.508
따라서 q의 두 번째 노드를 보면

00:42:15.508 --> 00:42:18.175
이것은 q의 L2 norm과 같습니다.

00:42:19.260 --> 00:42:24.218
이것은 q1의 제곱과 q2의 제곱을 합친 것과 같습니다.

00:42:24.218 --> 00:42:25.923
네 이것을 채워넣었습니다.

00:42:25.923 --> 00:42:29.423
우리는 q를 구했고 최종 출력을 구했습니다.

00:42:30.491 --> 00:42:33.218
좋아요, 이제 이것에 대해 backpropagation을 해봅시다.

00:42:33.218 --> 00:42:40.500
출력에 대한 gradient를 가지고 있고 이것은 1입니다. 이것은 항상 첫 단계입니다.

00:42:44.084 --> 00:42:47.505
이제 한 노드 뒤로 이동합시다.

00:42:47.505 --> 00:42:50.902
우리는 L2 이전의 중간 변수인 q에 대한 gradient를 찾기 원합니다.

00:42:50.902 --> 00:42:58.719
 그리고 q는 2차원의 벡터입니다.

00:42:58.719 --> 00:43:04.232
그리고 우리가 진짜 원하는것은 q의 각각의 요소가 f의 최종 값에 어떤 영향을 미치는지 입니다.

00:43:07.918 --> 00:43:09.586
그리고아래에 f를 위한 식을 적어놓았습니다.

00:43:09.586 --> 00:43:11.955
여기서 우리는 바닥에 f를 위해
를 써 넣었습니다.  우리는 f

00:43:11.955 --> 00:43:14.705
qi에 대한 f의 gradient를 볼 수 있습니다.

00:43:15.644 --> 00:43:19.293
이것을 q1이라고 부르겠습니다.

00:43:19.293 --> 00:43:23.136
이것은 qi * 2가 될 것입니다. 그렇죠?

00:43:23.136 --> 00:43:26.569
이것은 도함수를 구하는 것이고, 우리는 이것에 대한 식을 가지고 있습니다.

00:43:26.569 --> 00:43:32.453
 각각의 요소 qi에 대해서.

00:43:32.453 --> 00:43:34.606
우리는 또한 이것을 벡터의 형태로 쓸 수 있습니다.

00:43:34.606 --> 00:43:39.869
 이것은 우리의 벡터 q에 대해서 2를 곱한 것이었습니다.
그렇죠?

00:43:39.869 --> 00:43:41.719
그리고 우리는 이 벡터에서 gradient를 0.44와 0.52를 얻었습니다.

00:43:41.719 --> 00:43:50.656
 그리고 여러분은 그것이 q를 취해 단순히 2로 곱한것임을 보았습니다.

00:43:50.656 --> 00:43:55.192
 각 요소는 2로 곱해졌습니다.

00:43:55.192 --> 00:43:58.772
벡터의 gradient는 항상 원본 벡터의 사이즈와 같습니다.

00:43:58.772 --> 00:44:05.015
 그리고 gradient의 각 요소는 의미합니다.

00:44:06.530 --> 00:44:12.549
함수의 최종 출력에 얼마나 특별한 영향을 미치는지.

00:44:16.126 --> 00:44:18.920
좋아, 그럼 이제 한 걸음 뒤로 이동해봅시다.

00:44:18.920 --> 00:44:22.523
W의 gradient는 무엇입니까?

00:44:22.523 --> 00:44:25.639
그리고 여기에서 우리는 다시 chain rule을 사용할 것입니다.

00:44:25.639 --> 00:44:29.129
 우리가 W에 대한 q의 local
gradient를 계산하기 원한다면

00:44:29.129 --> 00:44:31.328
요소별 연산을 다시 해야할 것입니다.

00:44:31.328 --> 00:44:37.884
 각각의 q에 대한 영향을 봅시다.

00:44:37.884 --> 00:44:41.636
W의 각 요소에 대한 q의 각 요소 그리고 이것은

00:44:41.636 --> 00:44:43.106
이전에 말했던 Jacobian일 것입니다.

00:44:43.106 --> 00:44:47.592
그리고 우리는 곱셈의 형태로 볼  수 있습니다.

00:44:47.592 --> 00:44:49.509
여기에서 q는 W*x와 같습니다.

00:44:49.509 --> 00:44:53.092
q의 첫번째 요소의 gradient는 무엇입니까?

00:44:56.236 --> 00:44:59.197
도함수 또는 첫 번째 요소의 기울기이므로

00:44:59.197 --> 00:45:03.962
W11에 대한 첫 번째 요소가 위로 올라갑니다.

00:45:03.962 --> 00:45:07.470
그래서 W11에 대한 q1

00:45:07.470 --> 00:45:09.157
그 값은 무엇입니까?

00:45:09.157 --> 00:45:10.851
x1, 정확합니다.

00:45:10.851 --> 00:45:14.068
우리는 이것이 x1인 것을 알고있죠.

00:45:14.068 --> 00:45:21.826
그리고 우리는 이것을 Xj와 동일한 Wi,j에 대한 qk의 식으로 일반화 할 수 있습니다.

00:45:24.313 --> 00:45:30.278
그리고 우리는 f에 대한 gradient를 찾기 원합니다. 각 Wij에 대해서

00:45:31.523 --> 00:45:35.332
이것들의 도함수를 봅시다.

00:45:35.332 --> 00:45:38.339
우리는 chain rule을 사용할 수 있습니다.

00:45:38.339 --> 00:45:41.672
여기에서 기본적으로 qk에 대한 f의 미분을 합성 할 때

00:45:43.770 --> 00:45:47.270
Wij의 각 요소인 dqk/Wij의 각 요소에 대해합니다. 그렇죠?

00:45:48.934 --> 00:45:53.563
 그래서 우리는 W의 각 요소들의
영향을 찾을 수 있습니다.

00:45:53.563 --> 00:45:57.649
q의 각 요소들에 대해서, 그리고 모든 q에 대해 이것들을 모두 더합니다.

00:45:57.649 --> 00:46:03.236
그리고 만약 당신이 이것을 적다보면 이것은 결국
2 * qi * xj와 같은 식을 나타냅니다.

00:46:05.898 --> 00:46:08.744
좋아요, 우리가 구한 W에 대한 gradient를 채우면

00:46:08.744 --> 00:46:14.270
 각 요소들에 대해 다시 계산할 수 있습니다.

00:46:14.270 --> 00:46:20.943
또는 우리가 유도한 식을 벡터화된 형식으로 작성할 수 있습니다.

00:46:22.028 --> 00:46:24.827
좋아요, 중요한 것은 변수에 대해 gradient를 항상 체크하는 것이에요.

00:46:24.827 --> 00:46:31.137
 이것들은 항상 변수와 같은
모양(shape)을 가지고 있습니다.

00:46:31.137 --> 00:46:40.709
gradient가 무엇인지 계산을 했으면 이것이 변수의 모양과 동일한지 확인하세요.
이것은 검사하는데 있어서 매우 유용합니다.

00:46:42.710 --> 00:46:53.343
다시 말해, gradient의 요소는 정량화합니다, 얼마나 최종 출력에 영향을 미치는지를.

00:46:54.177 --> 00:46:55.010
응?

00:46:55.010 --> 00:46:57.489
[학생이 마이크로 말하는 중]

00:46:57.489 --> 00:47:04.177
양쪽 모두 지시 함수(indicator function)입니다.
이것은 k와 i가 같으면 1임을 의미합니다.

00:47:08.276 --> 00:47:11.571
좋아요, 봅시다.

00:47:11.571 --> 00:47:14.738
이제 또 하나의 예제를 보겠습니다.

00:47:16.647 --> 00:47:21.031
이제 우리가 찾아야 할 마지막 것은
qI에 대한 gradient입니다.

00:47:21.031 --> 00:47:28.574
dqk/dxi가 Wki와 같은 것을 볼 수 있습니다.

00:47:29.535 --> 00:47:32.702
우리가 W에 했던 것과 같은 방식으로

00:47:34.833 --> 00:47:38.702
그리고 다시 우리는 체인 규칙을 사용할 수 있습니다.

00:47:38.702 --> 00:47:44.902
그리고 그것에 대한 총 표현식을 얻을 수 있습니다. 아시겠습니까? 그리고
이것은 x와 같은 모양을 가진 x에 대한 gradient가 될 것입니다.

00:47:44.902 --> 00:47:52.022
 또한 이것을 벡터 형식으로 쓸 수 있습니다.

00:47:53.529 --> 00:47:56.442
좋아요, 그럼 이것에 대한 질문은 없습니까?

00:47:56.442 --> 00:47:59.100
[학생이 마이크로 말하는 중]

00:47:59.100 --> 00:48:01.850
우리는 Jacobian을 계산하는 중입니다.

00:48:03.194 --> 00:48:05.694
뒤로 한번 돌아가보죠.

00:48:07.414 --> 00:48:10.774
계산하는 중에 우리는 xi에 대한 qk의 편도함수를 가지고 있습니다.

00:48:10.774 --> 00:48:16.439
 그리고 이것들은 Jacobian 행렬을 구성합니다.
맞죠?

00:48:16.439 --> 00:48:26.306
 그리고 실제로 우리가 할 일은 이것을 가져와서

00:48:26.306 --> 00:48:29.222
x에 대한 gradient의 벡터화된 표현으로써 chain rule에서 사용하는 것입니다.

00:48:29.222 --> 00:48:33.293
 여기에 Jacobian 행렬이 있습니다.
이것은 전치된 값입니다.

00:48:33.293 --> 00:48:38.926
 당신은 이것을 벡터화된 형식으로 쓸 수 있습니다.

00:48:38.926 --> 00:48:43.489
[학생이 마이크로 말하는 중]

00:48:43.489 --> 00:48:51.803
이 행렬의 경우 W와 크기와 같습니다.
그리고 이 행렬은 큰 경우는 아닙니다.

00:48:55.878 --> 00:48:58.941
그래서 우리가 생각한 방식은 computational graph에서 실제로 모듈화 된 구현과 같습니다.

00:48:58.941 --> 00:49:10.965
 우리는 각 노드를 local하게 보았고 upstream gradient와 함께
chain rule을 이용해서 local gradient를 계산했습니다.

00:49:10.965 --> 00:49:19.186
이것을 forward pass, 그리고 backward pass의 API로 생각할 수 있습니다.
forward pass에서는 노드의 출력을 계산하는 함수를 구현하고

00:49:19.186 --> 00:49:25.011
 backward pass에서는
gradient를 계산합니다.

00:49:25.011 --> 00:49:27.295
그래서 우리가 실제로 코드에서 이것을 구현한다면,

00:49:27.295 --> 00:49:30.592
우리는 똑같은 방식으로 이 작업을 수행 할 것입니다.

00:49:30.592 --> 00:49:34.865
각각의 gate에 대해 생각해 볼 수 있습니다.

00:49:34.865 --> 00:49:40.908
forward, backward 함수를 구현할 때
backward 함수는 chain rule을 이용해 계산하고

00:49:40.908 --> 00:49:45.572
만약 우리가 완전한 그래프를 가지고 있으면

00:49:45.572 --> 00:49:48.833
그래프의 모든 노드를 반복함으로써 전체 그래프를 forward pass로 통과시킬 수 있습니다.

00:49:48.833 --> 00:49:54.768
 여기에서는 게이트와 노드라는 단어를 사용하려고 합니다. 이
모든 게이트를 반복하여 각 게이트를 호출할 수 있습니다.

00:49:54.768 --> 00:50:01.349
 그리고 우리는 이것을 위치적으로
정렬 된 순서로 수행하기를 원합니다.

00:50:01.349 --> 00:50:03.357
우리는 노드를 처리하기 전에 이 전에 노드로 들어오는 모든 입력을 처리합니다.

00:50:03.357 --> 00:50:15.482
 그리고 backward로 보면, 역순서로 모든 게이트를
통과한 다음에 게이트 각각을 거꾸로 호출합니다.

00:50:16.564 --> 00:50:22.285
좋아요, 그러면 특정 게이트에 대한 구현
살펴보면 여기에 곱셈 게이트가 있습니다.

00:50:22.285 --> 00:50:26.960
 이것의 forward pass를 구현하려고 합니다.

00:50:26.960 --> 00:50:31.127
이것은 x,y를 입력으로 받고 z를 리턴합니다.

00:50:32.520 --> 00:50:40.167
그리고 backward로 진행 할 때는 입력으로 upstream gradient인
dz를 받고 출력으로 입력인 x와 y에 gradient를 전달할 것입니다.

00:50:40.167 --> 00:50:45.190
 그래서 여기서 출력은 dx와 dy입니다.

00:50:46.426 --> 00:50:51.567
그리고 이 예제의 경우 모든 것은 scalar 입니다.

00:50:51.567 --> 00:50:57.215
그리고 forward pass를 보면 중요한 것은

00:50:57.215 --> 00:51:03.156
forward pass의 값을 저장(cache)해야 하는 것입니다. 왜냐하면 이것(forward
pass)이 끝나고 backward pass에서 더 많이 사용하기 때문입니다.

00:51:03.156 --> 00:51:06.061
그리고 forward pass에서 x와 y도 저장하는데

00:51:06.061 --> 00:51:10.594
backward pass에서 chain rule을 사용하여

00:51:10.594 --> 00:51:12.930
upstream gradient 값을 이용해 다른 브랜치의 값과 곱합니다.

00:51:12.930 --> 00:51:20.294
 self.y 와 dz를 곱해 얻은
dx를 보관하게 될 것입니다.

00:51:20.294 --> 00:51:25.877
 dy에 대해서도 마찬가지입니다.

00:51:28.799 --> 00:51:32.879
네 이제 딥러닝 프레임워크 그리고 라이브러리를 보면

00:51:32.879 --> 00:51:35.358
그들은 이러한 종류의 모듈화를 따릅니다.

00:51:35.358 --> 00:51:42.040
 예를들면 Caffe는 유명한 딥러닝 프레임워크입니다.

00:51:43.284 --> 00:51:46.047
그리고 당신은 Caffe의 소스 코드를 볼 수 있습니다.

00:51:46.047 --> 00:51:48.351
당신은 layer라고 부르는 폴더를 구할 수 있으며

00:51:48.351 --> 00:51:54.400
레이어는 기본적으로 computational node이고 보통 레이어는
sigmoid 처럼 당신이 생각하는 것보다 좀 더 복잡합니다.

00:51:54.400 --> 00:52:01.555
 computational 노드의 전체 목록 볼 수 있습니다.
그렇죠?

00:52:01.555 --> 00:52:06.132
 당신은 sigmoid를 가질 수
있고 여기에 있을것 같네요,

00:52:06.132 --> 00:52:09.205
convolution 같은 것도 여기에 있네요

00:52:09.205 --> 00:52:11.925
Argmax도 다른 레이어로 있습니다.

00:52:11.925 --> 00:52:16.340
당신은이 모든 레이어들을 가지게 될 것입니다. 만약 당신이 이것들을 탐구하면 정확하게
forward pass, backward pass 등을 구현할 수 있습니다.

00:52:16.340 --> 00:52:20.929
 이 모든 것들은 호출됩니다.

00:52:20.929 --> 00:52:27.372
우리가 만든 전체 네트워크를 통해 forward/backward pass 할 때,
그래서 우리의 네트워크는 기본적으로

00:52:27.372 --> 00:52:30.393
우리가 네트워크에 사용하기위해 선택한 레이어들을 쌓게 됩니다.

00:52:30.393 --> 00:52:37.560
 이 경우 우리는 sigmoid
레이어를 살펴볼 수 있습니다.

00:52:37.560 --> 00:52:44.658
 우리는 sigmoid 함수에 대해서 이야기 했었습니다.

00:52:44.658 --> 00:52:47.140
그것의 forward pass를 볼 수 있습니다.

00:52:47.140 --> 00:52:53.084
sigmoid 식과 똑같은 계산을 합니다.
그리고나서 backward pass로 전달합니다.

00:52:53.084 --> 00:52:57.251
여기서 upstream gradient인 top_diff를 취합니다.

00:53:00.031 --> 00:53:06.325
 그리고 우리가 계산한 local
gradient와 그것을 곱합니다.

00:53:08.267 --> 00:53:10.539
그래서 과제 하나에서는 이런 종류의 연습을 하게 될 것입니다.

00:53:10.539 --> 00:53:16.829
 computational graph 방식으로
SVM과 Softmax 클래스를 작성하고

00:53:16.829 --> 00:53:21.041
 이들의 gradient를 구할 수 있습니다.

00:53:21.041 --> 00:53:24.005
항상 기억하세요 첫번째 스텝은 computational graph로 나타내는 것입니다.

00:53:24.005 --> 00:53:29.492
 출력으로 이어지는 모든 계산이 무엇인지 파악한 다음

00:53:29.492 --> 00:53:32.928
 역방향 계산을 해야할 때

00:53:32.928 --> 00:53:35.786
computational graph에서 정의한, 계산에 필요한 중간 변수에 대한 gradient를 가져옵니다.

00:53:35.786 --> 00:53:42.262
 당신이 계산 그래프에서 정의한

00:53:42.262 --> 00:53:46.345
그리고 chain rule을 이용해서 연결합니다.

00:53:47.630 --> 00:53:50.726
좋아, 지금까지 얘기 한 내용을 요약해 보겠습니다.

00:53:50.726 --> 00:53:55.112
신경망으로 작업 할 때, 이것들은
정말로 크고 복잡 할 것입니다.

00:53:55.112 --> 00:54:04.864
그래서 모든 파라미터에 대해 gradient를 손으로 구하고 써내려가는 것은 비현실적입니다.
그래서 gradient를 계산하기 위해서

00:54:04.864 --> 00:54:08.866
backpropagation을 사용하는 방법에 대해서 이야기했었습니다.

00:54:08.866 --> 00:54:15.809
그리고 이것은 신경망의 핵심 기술이고, gradient를 구하기
위해서 backpropagation을 썼습니다. 그렇죠?

00:54:16.660 --> 00:54:23.942
 그리고 이것은 우리가 가지고 있는 computational
graph에서 chain rule을 재귀적으로 적용한 것입니다.

00:54:23.942 --> 00:54:26.298
우리는 뒤에서부터 시작하여 거슬러 올라갔습니다.

00:54:26.298 --> 00:54:35.369
입력이나, 파라미터 등등 모든
중간 변수들을 구하기 위해,

00:54:35.369 --> 00:54:42.746
그리고 각각의 노드에 대한 그래프 구조의 구현이 실제로 얼마나 큰지 이것들을
forward, backward API 구현으로 나타내는지에 대해서 이야기 했었습니다.

00:54:42.746 --> 00:54:51.937
 그리고 forward pass에서 우리는
연산 결과를 계산하고 결과를 저장합니다.

00:54:51.937 --> 00:54:55.149
그것은 나중에 우리가 gradient를 계산할 때 backward pass에서 chain rule에서 사용하기 위한 것이고

00:54:55.149 --> 00:55:00.200
 upstream gradient와 저장한 값들을 곱해

00:55:00.200 --> 00:55:11.323
 각 노드의 input에 대한 gradient를 구합니다.
그리고 우리는 그것들을 연결된 이전 노드로 통과시킵니다.

00:55:12.906 --> 00:55:21.600
좋아요, 이제 마지막으로 신경망에 대해서 이야기 해 봅시다. 사람들은
신경망과 뇌 사이에서 많은 유추와 여러 종류의 생물학적 영감을 이끌어냅니다.

00:55:24.254 --> 00:55:33.266
 우리는 그것에 대해 조금 배우겠지만,
일단 그것에 대해 이야기해봅시다.

00:55:33.266 --> 00:55:34.670
우리는 아시다시피 뇌 기능이 없는, 그저 함수 클래스로서 그것들을 보았었습니다.

00:55:34.670 --> 00:55:46.573
 우리가 지금까지 이야기한것은 우리는 다양한 선형 score 함수를 이용했었습니다.
f = W*x, 우리는 이것을

00:55:46.573 --> 00:55:56.162
최적화할 때의 실행 예제로 사용했었습니다. 그러면 single 변환을
사용하는 대신에 아주 간단한 형태의 신경망을 사용해봅시다.

00:55:57.138 --> 00:56:08.122
 위에 있는 것은 선형 변환식이고 다른 하나는
2층짜리 신경망의 레이어입니다. 그렇죠?

00:56:08.122 --> 00:56:11.451
이것이 어떻게 생겼나요, 첫번째로 알다시피

00:56:11.451 --> 00:56:14.284
W1과 x의 행렬 곱입니다.

00:56:15.921 --> 00:56:23.509
그리고 우리는 이것의 중간값을 얻고, 우리가
가진 max(0, W)의 비선형 함수를 이용해

00:56:24.761 --> 00:56:28.706
선형 레이어 출력의 max를 얻습니다.

00:56:28.706 --> 00:56:32.093
그리고 이 비선형 변환은 매우 중요합니다.

00:56:32.093 --> 00:56:38.203
나중에 이것에 대해 더 이야기하겠습니다. 만약 당신이 선형
레이어들을 쌓는다면 그것들은 결국 선형 함수가 될 것입니다.

00:56:38.203 --> 00:56:45.846
 자 우리는 첫번째 선형 레이어를 같고 있습니다.
그 다음 우리는 비선형 레이어를 가지고 있습니다.

00:56:45.846 --> 00:56:49.347
그리고 이것의 위에 선형 레이어를 추가할 것입니다.

00:56:49.347 --> 00:56:52.310
여기에서 최종적으로 우리는 score 함수를 얻을 수 있습니다.

00:56:52.310 --> 00:57:02.652
 그래서 기본적으로 광범위하게 말하면 신경망은 함수들의 집합(class)입니다.
비선형의 복잡한 함수를 만들기 위해서 간단한 함수들을 계층적으로 여러개 쌓아올린.

00:57:02.652 --> 00:57:13.827
 그리고 이 아이디어는 여러 단계의 계층적
계산으로 이루어져 있습니다. 맞죠?

00:57:13.827 --> 00:57:19.455
 여러분이 알다시피

00:57:19.455 --> 00:57:22.589
이것은 우리가 하는 주된 방법중 하나입니다.

00:57:22.589 --> 00:57:33.871
행렬 곱, 중간에 비선형 함수와 함께 선형 레이어를 여러개 쌓아 계산하는 것입니다.

00:57:38.446 --> 00:57:43.135
그리고 이것이 이것들을 이해하는데 도움이 되는 한 가지는 이전에
선형 score 함수에 대해서 이야기 했던 것을 생각해보세요

00:57:43.135 --> 00:57:49.390
 우리의 가중치 행렬 W의 각 행이 각각의
템플릿과 같았는지를 논의했던 것을 기억해보세요.

00:57:49.390 --> 00:57:55.537
 그것은 일종의 표현된 템플릿이었습니다.

00:57:55.537 --> 00:57:58.697
우리가 구체적인 클래스에 대한 입력을 보면

00:57:58.697 --> 00:58:02.394
예를들면 자동차 템플릿은 이런
종류의 빨간 차처럼 보입니다.

00:58:02.394 --> 00:58:10.151
 입력에 대한 car 클래스 스코어를 계산합니다.

00:58:10.151 --> 00:58:13.566
우리는 하나의 문제에 대해서만 이야기했습니다. 이것은
오직 하나의 자동차 템플릿만 가지고 있습니다. 그렇죠?

00:58:13.566 --> 00:58:19.537
여기에는 빨간 차가 있습니다. 우리는 실제로 여러 모드가 있습니다. 우리는 빨간
차가 있는지 노란 차가 있는지, 다른 여러 종류의 차를 찾기 원할 수도 있습니다.

00:58:19.537 --> 00:58:28.210
 다중 레이어 네트워크는 그것을 가능하게 합니다.

00:58:29.287 --> 00:58:33.666
중간 변수 h와 W1은 이러한 종류의 템플릿일 수 있습니다.

00:58:33.666 --> 00:58:42.006
 하지만 h에서 이 템플릿들에 대한 모든 점수를 가지고 있습니다. 그리고
우리는 이것을 결합하는 또 다른 레이어를 가질 수 있습니다. 그렇죠?

00:58:42.006 --> 00:58:50.525
 그래서 실제로 차 클래스가 연결되어야 한다고 말할 수 있습니다.
우리는 빨간 차와 노란 차 모두를 찾기 원하므로.

00:58:50.525 --> 00:59:00.819
 h의 벡터에 대한 가중치인 W2 행렬을 가지고 있기 때문에

00:59:05.691 --> 00:59:08.478
좋아, 이것에 대해 질문이 있으십니까?

00:59:08.478 --> 00:59:09.311
그래?

00:59:09.311 --> 00:59:13.795
[학생이 마이크로 말하는 중]

00:59:13.795 --> 00:59:17.189
네, 많은 방법이 있습니다. 당신이 선택할 수
있는 다른 비선형 함수가 많이 있습니다.

00:59:17.189 --> 00:59:20.821
당신이 사용할 수 있는 여러 비선형들에 대해서 추후 강의에 이야기 할 것입니다.

00:59:20.821 --> 00:59:28.599
 [학생] 슬라이드의 그림에서

00:59:28.599 --> 00:59:34.828
[학생] 아래에는 W1 가중치에 대한 그림이 있습니다.

00:59:38.703 --> 00:59:42.536
[학생] W2에 대한 그림이있습니까?

00:59:46.014 --> 00:59:52.965
W1은 입력과 직접적으로 연결되어 있죠 그래서 이
템플릿을 공식화 할 수 있기 때문에 해석가능한 것입니다.

00:59:52.965 --> 00:59:59.492
 W2는 h의 스코어가 될 것입니다.

01:00:00.389 --> 01:00:09.640
얼마나 많은 점수를 얻었는지를 알 수 있습니다. W2는 당신이 가지고
있는 것처럼 나올 것입니다. 나는 그것을 예측할 수 없습니다.

01:00:09.640 --> 01:00:19.327
 [학생] W1이 10인 경우 말고, 만약 오른쪽을 향하고 있는
말과 왼쪽을 향하고 있는 말을 동시에 표현할 수 있습니까?

01:00:19.327 --> 01:00:25.864
 네, 정확히 말하자면 W1이 왼쪽으로 향해있는 말과

01:00:25.864 --> 01:00:34.590
오른쪽으로 향해있는 말을 모두 가질 수 있는지인데요, 그렇습니다.
W1은 많은 다른 종류의 템플릿이 될 수 있습니까?

01:00:34.590 --> 01:00:38.505
안됩니다. 그리고 W2는 모든 템플릿의 가중치를 합한 것입니다.

01:00:38.505 --> 01:00:43.461
 그것은 특정 클래스에 대한 최종 스코어를 얻기 위해

01:00:43.461 --> 01:00:47.014
여러 템플릿의 가중치를 합할 수 있게 해줍니다.

01:00:47.014 --> 01:00:53.522
[학생] 만약 실제로 왼쪽으로 향하고 있는 말의 이미지를 이용해 작업을
하면 왼쪽을 향하는 말의 템플릿에서 높은 점수를 얻고

01:00:53.522 --> 01:00:58.186
 [학생] 오른쪽을 향하고 있는
말에서는 낮은 점수를 얻겠죠

01:00:58.186 --> 01:01:02.552
[학생]그러면 이것의 최대값을 구합니까?

01:01:02.552 --> 01:01:10.519
질문은 만약 우리의 이미지 x가 왼쪽을 향하고 있는
말이고 그리고 W1이 왼쪽을 향하고 있는 말의 템플릿과

01:01:10.519 --> 01:01:14.435
오른쪽을 향하고 있는 말의 템플릿을 가질 때,
이때 어떤일이 일어나는지에 대해서였습니다.

01:01:14.435 --> 01:01:17.390
무슨일이 일어날까요?

01:01:17.390 --> 01:01:21.199
h에서 왼쪽을 향하고 있는 말은 점수가 높게 나올 것이고,

01:01:21.199 --> 01:01:24.627
오른쪽을 향하고 말에 대해서는 낮은 점수를 얻을 것입니다.

01:01:24.627 --> 01:01:30.749
그리고 W2는 가중치들의 합입니다. 따라서 최대값이 아닙니다.
이것은 템플릿들의 가중치의 합계입니다.

01:01:30.749 --> 01:01:35.597
하지만 이 템플릿중 하나에 대해서 정말로 높은 점수를 얻었거나 두
템플릿 모두에 대해서 낮거나 중간의 점수를 얻었다고 해봅시다.

01:01:35.597 --> 01:01:39.968
이것들의 조합은 둘다 높은 점수를 얻을 것입니다.
그렇죠?

01:01:39.968 --> 01:01:43.305
 결국 당신이 얻고 싶은 것은 특정한
종류의 말을 가지고 있을 때

01:01:43.305 --> 01:01:49.757
일반적으로 높은 점수를 얻는 것입니다. 어떤 종류의 말이라도 가지고
있을 때, 앞을 보고 있는 말을 가지고 있다고 해봅시다.

01:01:50.966 --> 01:01:56.901
당신은 아마 왼쪽, 오른쪽을 보는 말의 템플릿에
대해서 두개 다 중간정도의 점수를 가질 것입니다.

01:01:56.901 --> 01:01:57.963
질문있나요?

01:01:57.963 --> 01:01:59.994
[학생] W2가 가중치를 쓰고 있습니까? 아니면 H가 가중치를 쓰고 있습니까?

01:01:59.994 --> 01:02:09.710
 W2가 가중치를 쓰고 있습니다. 질문은 즉 "W-two가 가중치를 부여합니까,
아니면 h가 가중치를 부여하고 있습니까?" 이거죠? h는 값입니다.

01:02:09.710 --> 01:02:14.144
h는 W1에서 가지고 있는 템플릿에 대한 스코어 값입니다.

01:02:14.144 --> 01:02:21.128
 그래서 h는 스코어 함수입니다. 아시겠습니까?

01:02:21.128 --> 01:02:25.851
그것은 W1의 각 템플릿이 얼마나 많은지를 나타내주는 것이고

01:02:25.851 --> 01:02:31.341
W2는 이들 모두에 가중치를 부여하고 모든 중간
점수를 더해 클래스에 대한 최종 점수를 얻습니다.

01:02:31.341 --> 01:02:36.194
 [학생] 그것은 비선형입니까?

01:02:36.194 --> 01:02:42.171
비선형이냐는 질문이 있었는데요
h 이전에 비선형성이 발생하므로

01:02:43.643 --> 01:02:49.490
h는 비선형 값입니다. 우리는
이것에 대해 이야기하고 있습니다.

01:02:49.490 --> 01:02:53.928
이 예제에서 직관적으로 W1은 같은 템플릿을 찾는 것이고

01:02:53.928 --> 01:02:57.152
 그리고 W2는 이것들에 대한 가중치입니다.

01:02:57.152 --> 01:03:03.358
실제로는 정확히 이렇지는 않습니다. 왜냐하면 말했던
것처럼 비선형적인 것들이 나오기 때문입니다.

01:03:03.358 --> 01:03:07.525
이것들은 대략적인 해석을 가지고 있습니다.

01:03:08.435 --> 01:03:11.602
[학생] h는 W1*X 인가요?

01:03:13.811 --> 01:03:16.715
네네, 질문은 h는 W1*X인가 였는데요

01:03:16.715 --> 01:03:20.882
h는 딱 W1과 X의 곱입니다. max function을 위에 두고 있는.

01:03:27.004 --> 01:03:31.656
 우리는 이 두 레이어로 구성된
신경망에 대해서 이야기 했습니다.

01:03:31.656 --> 01:03:34.390
그리고 우리는 더 많은 레이어를 쌓아 임의의 깊은 신경망을 구성할 수 있습니다.

01:03:34.390 --> 01:03:39.202
 우리는 이것을 한번 더 곱해봅시다.

01:03:39.202 --> 01:03:48.347
다른 비선형 행렬 W3로 곱할 수 있습니다. 이제 우리는 3-레이어 신경망을 가지고 있습니다.
그렇죠? 이런것으로부터 깊은 신경망이라는 용어가 나오게 됩니다.

01:03:49.921 --> 01:03:57.831
 복잡한 네트워크의 경우 이러한 계층을
여러 개 쌓는 아이디어에서 나옵니다.

01:04:00.153 --> 01:04:03.486
과제를 하다보면 쓰기(writing) 연습을 하게 될 것입니다.

01:04:04.453 --> 01:04:10.363
 신경망 중 하나를 학습하다보면, 과제 2에서

01:04:10.363 --> 01:04:13.534
기본적으로 forward pass, backward pass를 완벽하게 구현하게 됩니다.

01:04:13.534 --> 01:04:22.924
 gradient를 구하기 위해 앞서 보았던 chain rule을 사용하게 됩니다.
2-레이어 네트워크의 전체 구현은 실제로 매우 단순합니다.

01:04:22.924 --> 01:04:27.444
이것은 20줄로 할 수 있습니다.

01:04:27.444 --> 01:04:31.131
그리고 당신은 이 과제 2에서 이 파트들을 쓰는 연습을 하게 될 것입니다.

01:04:31.131 --> 01:04:36.269
 우리는 신경망이 무엇인지를 함수로써 살펴보았습니다.

01:04:36.269 --> 01:04:41.005
 알다시피, 우리는 신경망에 대한 생물학적 영감에 대해

01:04:41.005 --> 01:04:44.613
많은 이야기를 하는것을 듣게 됩니다.

01:04:44.613 --> 01:04:47.816
이것을 강조하는것은 중요합니다.

01:04:47.816 --> 01:04:50.926
비록 분석이 실제로 loose 하지만

01:04:50.926 --> 01:04:56.303
이것은 정말로 loose한 관계입니다. 하지만 이러한 연결과
영감이 어디에서 왔는지 이해하는데 있어 여전히 흥미롭습니다.

01:04:56.303 --> 01:05:03.445
 이것에 대해서 간략하게 이야기해봅시다.

01:05:03.445 --> 01:05:05.712
뉴런에 대해서 생각해보면 그것은 단순합니다.

01:05:05.712 --> 01:05:11.270
 이것은 뉴런의 다이어그램입니다.

01:05:11.270 --> 01:05:19.503
우리는 각 뉴런을 따라 전달되는 신호를 가지고 있습니다. 그리고 우리는 서로 연결된
많은 뉴런을 가지고 있습니다. 그리고 각 뉴런은 수상돌기를 가지고 있습니다.

01:05:19.503 --> 01:05:22.008
그것들은 뉴런에 들어온 신호를 받습니다.

01:05:22.008 --> 01:05:26.706
 그리고 우리는 세포체(cell
body)를 가지고 있습니다.

01:05:26.706 --> 01:05:30.362
이것은 기본적으로 들어오는 신호를 종합합니다.

01:05:30.362 --> 01:05:34.018
이것들을 받아  합친 후에 모든 신호는

01:05:34.018 --> 01:05:42.543
 하류 뉴런과 연결된 다른 세포체로 이동합니다.

01:05:42.543 --> 01:05:46.376
이것은 축삭(axon)을 통해 운반됩니다.

01:05:48.337 --> 01:05:54.401
지금까지 우리가 해왔던 것을 보았을 때 각 computational
node는 실제 동작과 비슷한 방식으로 볼 수 있습니다.

01:05:54.401 --> 01:06:01.694
 노드가 computational
graph에서 서로 연결되어 있고

01:06:01.694 --> 01:06:05.688
입력 또는 신호는 x입니다. 뉴런에 들어가는 것처럼

01:06:05.688 --> 01:06:13.732
 모든 x0, x1, x2, 모든 x는

01:06:13.732 --> 01:06:16.712
우리의 가중치 W와 결합되어 합쳐집니다.

01:06:16.712 --> 01:06:25.109
 우리는 일종의 계산을합니다. 우리가 해왔던 일부
계산에서는 W를 x와 곱하고 b를 더했습니다.

01:06:25.109 --> 01:06:31.610
 모든것을 통합하였고 그리고 활성
함수를 꼭대기에 적용했습니다.

01:06:31.610 --> 01:06:36.931
 출력 값을 얻었고

01:06:36.931 --> 01:06:40.764
아래로 연결된 뉴런에 전달했습니다.

01:06:41.733 --> 01:06:44.068
이것을 보면 당신은 매우 비슷한 방식이라고 생각할 수 있습니다. 그렇죠?

01:06:44.068 --> 01:06:49.235
 알다시피 이것들은 들어오는 신호가
시냅스에서 연결되는 것들입니다. 그렇죠?

01:06:49.235 --> 01:06:56.289
 여러개의 뉴런과 연결된 시냅스, 그리고 수상돌기는

01:06:56.289 --> 01:06:59.745
세포체로 이 모든 정보를 합칩니다.

01:06:59.745 --> 01:07:04.226
 그리고 나서 우리는 출력을 실었습니다.

01:07:04.226 --> 01:07:10.261
 이것은 표현할 수 있는 일종의 비유입니다.

01:07:10.261 --> 01:07:15.240
 그리고 당신은 이 활성함수를 볼 수 있습니다. 그렇죠?

01:07:15.240 --> 01:07:18.710
이것은 입력을 받아 나중에 출력이 될 하나의 숫자를 보여주는 것입니다.

01:07:18.710 --> 01:07:23.131
 우리는 sigmoid 및 여러 종류의
비선형과 관련해서 이야기 했습니다.

01:07:23.131 --> 01:07:32.461
 그리고 이것은 loose한 종류입니다.

01:07:34.601 --> 01:07:37.340
당신은 비선형성으로 뉴런의 firing이나 spiking에 대해서 표현할 수 있습니다.

01:07:37.340 --> 01:07:46.771
 우리의 뉴런이 이산 spike 종류를
사용해서 신호를 전송합니다. 그렇죠?

01:07:46.771 --> 01:07:51.215
 알다시피 생각해볼 수 있습니다.

01:07:51.215 --> 01:07:58.266
그것들이 매우 빠르게 spiking 하는 경우 전달되는 강한 신호가 있습니다.
그래서 우리는 활성함수를 통과한 다음에 이 값을 생각할 수 있습니다.

01:07:58.266 --> 01:08:08.084
 알다시피 실제로, 이것을 연구하고 있는 신경 과학자들은

01:08:08.084 --> 01:08:11.614
 실제 방식과 가장 유사한 비선형성의 종류가

01:08:11.614 --> 01:08:19.560
 ReLU라고 말합니다.

01:08:19.560 --> 01:08:23.423
나중에 더 자세히 볼꺼지만 이것은 함수입니다.

01:08:23.423 --> 01:08:31.716
모든 음수 입력값에 대해서 0이고,
양수 입력에 대해서는 선형 함수인.

01:08:31.716 --> 01:08:35.362
 알다시피 우리는 활성함수에대해
나중에 더 이야기 할 것입니다.

01:08:35.362 --> 01:08:44.004
실제로 이것들은 뉴런들의 행동과 비슷하지만,

01:08:46.020 --> 01:08:49.046
실제 생물학적 뉴런은 이보다 훨씬 복잡하기 때문에

01:08:49.046 --> 01:08:52.056
이러한 종류의 신경을 만드는 것은 매우 신중해야 합니다.

01:08:52.057 --> 01:09:01.352
 생물학적 뉴런에는 여러 종류가 있습니다. 수상돌기는
실제로 복잡한 비선형 계산을 수행할 수 있습니다.

01:09:01.352 --> 01:09:07.884
 우리의 시냅스, 이전에 비유적으로 그렸던 W0은

01:09:07.884 --> 01:09:14.033
우리가 가진 것처럼 단일 가중치가 아니며,
실제로 엄청 복잡한 비선형 시스템입니다.

01:09:14.033 --> 01:09:21.602
 우리의 활성함수를 일종의 rate
code나 fire rate로 해석하는

01:09:21.602 --> 01:09:25.524
이러한 아이디어는 실제로는 불충분합니다.

01:09:25.524 --> 01:09:32.251
 이러한 종류의 firing rate는
충분한 모델이 아닐 것입니다.

01:09:32.251 --> 01:09:34.671
뉴런이 어떻게 하부의 뉴런과 통신하는지에 대해서.

01:09:34.671 --> 01:09:41.366
 아주 간단한 방법처럼 뉴런은 가변
fire rate로 발사할 것이고,

01:09:41.366 --> 01:09:44.549
이 가변성에 대해서 고려되어야 할 것입니다.

01:09:44.549 --> 01:09:49.913
 우리가 다루는 것보다 훨씬 복잡한 모든 것이 있습니다.

01:09:49.913 --> 01:10:00.692
 수상돌기의 계산에 예제에 관한 레퍼런스가 있습니다.

01:10:00.692 --> 01:10:03.944
이 주제에 관심이 있다면 살펴볼 수 잇습니다.

01:10:03.944 --> 01:10:08.701
하지만 실제로 알다시피, 우리는 높은 수준에서
많은 뉴런을 닮은 것들을 볼 수 있습니다.

01:10:08.701 --> 01:10:15.916
 하지만 실제로 그것들은 더 복잡합니다.

01:10:15.916 --> 01:10:18.998
우리는 사용될 수 있는 많은 다른 종류의 활성함수에 대해서 이야기 했습니다.

01:10:18.998 --> 01:10:25.820
 거기에는 앞서 언급한 ReLu도 있었습니다. 그리고 당신이
사용하고 싶어할 수 있는 다른 종류의 활성함수에 대해서

01:10:25.820 --> 01:10:29.828
나중에 자세히 다룰 것입니다.

01:10:29.828 --> 01:10:36.140
 그리고 우리는 다른 종류의 신경망에
대해서도 이야기 할 것입니다.

01:10:36.140 --> 01:10:42.825
 우리는 완전히 연결된 신경망 예제를 보았습니다.

01:10:44.362 --> 01:10:50.410
 각 레이어는 행렬곱을 했고,

01:10:52.362 --> 01:10:55.969
우리가 2-레이어 신경망이라고 불렀던 것은

01:10:55.969 --> 01:10:58.535
우리가 선형 레이어를 2개 가지고 있다는 사실에 입각했었습니다.

01:10:58.535 --> 01:11:04.374
 그것은 행렬 곱셈을 하는 완전히 연결된 두 층입니다.

01:11:04.374 --> 01:11:10.384
 이것을 하나의 히든 레이어 네트워크로 부를 수 있습니다.
행렬 곱의 수를 세는 대신에 히든 레이어를 셀 수 있습니다.

01:11:10.384 --> 01:11:17.654
 제 생각에는 두 가지 중 하나를 사용할 수 있습니다.

01:11:17.654 --> 01:11:24.033
아마 2-레이어 신경망이 조금 더 일반적으로 사용될 것 같습니다.
또한 여기에서 우리의 3-레이어 신경망은

01:11:24.033 --> 01:11:27.319
2-히든 레이어 신경망으로 부를 수 있습니다.

01:11:27.319 --> 01:11:36.759
 feed forward를 할 때 우리는 보았습니다.

01:11:36.759 --> 01:11:44.247
 네트워크 안의 각 노드에 forward
pass를 수행하는 것은

01:11:46.768 --> 01:11:53.587
이전에 보여주었던 뉴런의 행동과 같습니다. 맞나요?

01:11:55.875 --> 01:12:00.496
그리고 실제 동작에서 생각해볼 수 있는 것은 기본적으로
각 히든 레이어는 완전한 벡터인 것입니다.

01:12:00.496 --> 01:12:06.113
 이러한 행렬 곱셈을 통해

01:12:06.113 --> 01:12:10.828
우리의 뉴런 값을 계산하는 방식으로 쓰면

01:12:10.828 --> 01:12:13.163
우리는 뉴런의 전체 레이어를 효율적으로 평가할 수 있습니다.

01:12:13.163 --> 01:12:23.664
 따라서 하나의 행렬 곱셈을 사용하면 10,50 또는 100개의
뉴런을 의미하는 레이어의 출력값을 얻을 수 있습니다.

01:12:26.389 --> 01:12:31.082
좋아요, 그리고 다시 살펴보면

01:12:31.082 --> 01:12:34.597
우리가 가지고 있는 벡터 행렬 형태의 출력은 비선형성을 가집니다.

01:12:34.597 --> 01:12:40.743
 여기에서 사용한 F는 sigmoid 함수입니다.

01:12:40.743 --> 01:12:44.051
그리고 우리의 데이터는 x로 받습니다.

01:12:44.051 --> 01:12:48.226
첫 번째 행렬 곱 W1은 가장 윗줄에 있습니다.

01:12:48.226 --> 01:12:54.436
비선형성을 적용한 다음, 두 번째 히든 레이어
h2를 얻기 위한 두 번째 행렬곱을 합니다.

01:12:54.436 --> 01:12:59.183
 그리고 최종 출력을 얻습니다. 아시겠습니까?

01:12:59.183 --> 01:13:02.231
그리고 아시다시피 앞에서 보았던 backward pass는
신경망을 쓰기(write) 위해 기본적으로 필요할 것입니다.

01:13:02.231 --> 01:13:11.199
 그리고 모든 것을 계산하기 위해
backpropagation을 쓰기만 하면 됩니다.

01:13:11.199 --> 01:13:24.115
 그리고 신경망이 무엇인지에 대한 주요 아이디어가 있습니다. 요약하자면, 어떻게 뉴런을
선형 레이어와 fully-connected로 재배열하는지에 대해서 이야기했습니다.

01:13:24.115 --> 01:13:34.642
 이 레이어의 추상화는 이 모든
것을 계산하는데 매우 효율적인

01:13:34.642 --> 01:13:42.628
벡터화된 코드를 사용할 수 있게 하는 좋은 속성을 가지고 있습니다.
우리는 또한신경망이 생물학적 비유와 loose한 영감을 가지고 있음을

01:13:42.628 --> 01:13:45.805
명심하는 것이 얼마나 중요한지에 대해 이야기 했습니다.
하지만 실제로는 신경이 아닙니다.

01:13:45.805 --> 01:13:50.692
 제 말은 즉 우리가 만들고 있는 것은
꽤나 loose한 유추라는 것입니다.